<?php

namespace app\common\service;

use PHPSocketIO\SocketIO;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;

class Socket {


    public static function start()
    {
        if (config('socketio.open_ssl')) {
            $context = config('socketio.context');
            if (env('SSL.ALLOW_SELF_SIGNED')) {
                $context['ssl']['allow_self_signed'] = true;
            }

            // PHPSocketIO服务
            $sender_io = new SocketIO(config('socketio.ws_port'), $context);
        } else {
            // PHPSocketIO服务
            $sender_io = new SocketIO(config('socketio.ws_port'));
        }

        // 客户端发起连接事件时，设置连接socket的各种事件回调
        $sender_io->on('connection', function($socket) {
            
            // 当客户端发来登录事件时触发
            $socket->on('login', function ($uid) use ($socket) {

                // 将这个连接加入到uid分组，方便针对uid推送数据
                $socket->join($uid);
                $socket->uid = $uid;
            });

            // 当客户端断开连接是触发（一般是关闭网页或者跳转刷新导致）
            $socket->on('disconnect', function () use ($socket) {
                if (!isset($socket->uid)) {
                    return;
                }
            });
        });

        // 当$sender_io启动后监听一个http端口，通过这个端口可以给任意uid或者所有uid推送数据
        $sender_io->on('workerStart', function() use ($sender_io) {
            // 监听一个http端口
            $inner_http_worker = new Worker('http://127.0.0.1:' . config('socketio.http_port'));
            // 当http客户端发来数据时触发
            $inner_http_worker->onMessage = function(TcpConnection $http_connection, Request $request) use ($sender_io) {

                $post = $request->post();
                $post = $post ? $post : $request->get();
                $id =  $post['to'];
                // 推送数据
                switch (@$post['type']) {
                    // 登陆验证
                    case 'login_verified':
                        $sender_io->to($id)->emit($post['type'], $post['scene_id']);
                        break;
                }

                // http接口返回，如果用户离线socket返回fail
                return $http_connection->send('ok');
            };

            // 执行监听
            $inner_http_worker->listen();
        });

        if(!defined('GLOBAL_START')) {
            Worker::runAll();
        }
    }
}